module Alu (

    input   [31:0] a,
    input   [31:0] b,
    input   [2:0]  op,
    output  [31:0] aluout,
    input          unsig,
    output         compout,
    output         overflow

    );

    reg [31:0] c;
    reg [0:0]  over;
    reg [0:0]  comp;

    assign aluout = c;
    assign overflow = over;
    assign compout = comp;

    always @(a or b or op or unsig) begin

	over = 0;

	// Execute the operation.
        case (op)
            // *** AND ***
            3'b000 : begin
                c = a & b;
            end

            // *** OR ***
            3'b001 : begin
                c = a | b;
            end

            // *** ADD ***
            3'b010 : begin
                c = a + b;
                
                // Overflow verification.
                if (a[31] == 1'b0 && b[31] == 1'b0 && c[31] == 1'b1) 
                    over = 1'b1;    
                if (a[31] == 1'b1 && b[31] == 1'b1 && c[31] == 1'b0) 
                    over = 1'b1;                 
            end

            // No Operation
            3'b011 : begin
                // Nothing
            end

            // *** NOR ***
            3'b100 : begin
                c = ~(a | b);
            end

            // *** XOR ***
            3'b101 : begin
                c = a ^ b;
            end

            // *** SUB ***
            3'b110 : begin
                c = a - b;

                // Overflow verification.
                if (a[31] == 1'b1 && b[31] == 1'b0 && c[31] == 1'b0)
                    over = 1'b1;
                if (a[31] == 1'b0 && b[31] == 1'b1 && c[31] == 1'b1) 
                    over = 1'b1;    
            end

            // No Operation.
            3'b111 : begin
                // Nothing.
            end
        endcase 

        // Refresh compout.
	comp = 1'b0;
        if (unsig == 1'b0) begin
          
            // If a is negative and b is positive, b > a.
            if (a[31] == 1'b1 && b[31] == 1'b0)
                comp = 1'b1;
           
            // If a is positive and b is positive, we have to compare.
            if (a[31] == 1'b0 && b[31] == 1'b0)
                if (a < b)
                    comp = 1'b1;

            // If both is negative, we have to compare.
            if (a[31] == 1'b1 && b[31] == 1'b1)
                // If we negate both in tow complement, the smallest value  
                // will be come the biggest value, vice-versa.
                if ( ~a > ~b)
                    comp = 1'b1;
	end

        if (unsig == 1'b1) begin
            if (a < b)
               comp = 1'b1; 
        end
    end // Always.
    
endmodule

